home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 6 / MacMania 6.toast / / Multimedia & Desktop / sk8 / SK8InJava / Code / Collections / ChunkedTextCollection.java < prev    next >
Encoding:
Java Source  |  1997-02-27  |  5.2 KB  |  188 lines  |  [TEXT/CWIE]

  1. /*  SK8 © 1997 Apple Computer, Inc.
  2.     This code is protected under the current SK8 License
  3.     See http://sk8.research.apple.com/ for more information
  4.     Apple Research Laboratories
  5. */
  6.  
  7.  
  8.  
  9.  
  10. public abstract class chunkedtext extends text {
  11.  
  12.     /**
  13.      ** Constructors
  14.      **/
  15.      public chunkedtext(StringBuffer inString){
  16.          super(inString);
  17.      }
  18.      
  19.      public chunkedtext(String inString){
  20.          super(inString);
  21.      }
  22.          
  23.     
  24.     /**
  25.      ** collection protocol stuff...
  26.      **/    
  27.      
  28.     /**
  29.      ** initialvisitstate
  30.      **/    
  31.     public visitstate initialvisitstate() {
  32.          return new chunkedtextvisitstate(this, 0); 
  33.     }
  34.              
  35.      
  36.      /**
  37.      ** isfinalvisitstate
  38.      **/    
  39.      public boolean isfinalvisitstate(visitstate inState) {
  40.         checkVisitStateType(inState);
  41.         int nextChunkBounds[] = nextChunk(((textvisitstate)inState).mCurrentPosition);
  42.         nextChunkBounds = nextChunk(nextChunkBounds[1] + 1);
  43.         return (nextChunkBounds[0] == stringLength());
  44.      }
  45.      
  46.     
  47.     /**
  48.      ** succeedingvisitstate
  49.      **/    
  50.       public visitstate succeedingvisitstate(visitstate inState) {
  51.         checkVisitStateType(inState);
  52.         
  53.         if (isfinalvisitstate(inState))
  54.             return null;//    throw new collectionexception("Can't get succeeding state from a final state");
  55.         int nextChunkBounds[] = nextChunk(((textvisitstate)inState).mCurrentPosition);
  56.         ((chunkedtextvisitstate)inState).mCurrentPosition = nextChunkBounds[1] + 1;
  57.         ((chunkedtextvisitstate)inState).mCurrentChunkIndex++;
  58.         return inState;
  59.     }
  60.     
  61.     
  62.     /**
  63.      ** elementatvisitstate
  64.      **/    
  65.      public Object elementatvisitstate(visitstate inState) {
  66.         checkVisitStateType(inState);
  67.         int ChunkedTextBoundries[] = nextChunk(((textvisitstate)inState).mCurrentPosition);
  68.         char dest[] = new char[ChunkedTextBoundries[1] - ChunkedTextBoundries[0]];
  69.         getChars(ChunkedTextBoundries[0],ChunkedTextBoundries[1],dest, 0);
  70.         return new String(dest);
  71.     }
  72.     
  73.     
  74.     /**
  75.      ** setelementatvisitstate
  76.      **/    
  77.      public void    setelementatvisitstate(visitstate inState, Object inElement)  {
  78.         checkVisitStateType(inState);
  79.         
  80.         char ch = '\u0000'; //so we don't get "maybe uninitialized" error
  81.         boolean inputIsOK = false;
  82.         
  83.         if (inElement instanceof Character){
  84.             ch = ((Character)inElement).charValue();
  85.             inputIsOK = true;
  86.         }
  87.             
  88.         if ((inElement instanceof String) && (((String)inElement).length()) == 1) {
  89.             ch = ((String)inElement).charAt(0);
  90.             inputIsOK = true;
  91.         }
  92.         
  93.         if (! inputIsOK)
  94.             throw new IllegalArgumentException("Incorrect value type");
  95.             
  96.         setNthChar(((textvisitstate)inState).mCurrentPosition, ch);
  97.     }
  98.                                     
  99.     /**
  100.      ** removevisitstate
  101.      **/    
  102.      public void removevisitstate(visitstate inState)  {
  103.         checkVisitStateType(inState);
  104.         int startingAt = ((chunkedtextvisitstate)inState).mCurrentPosition;
  105.         
  106.         int[] chunkBounds = nextChunk(startingAt);
  107.         removeChars(startingAt , chunkBounds[1]);
  108.  
  109.     }
  110.                                     
  111.     /**
  112.      ** insertatvisitstate
  113.      **/    
  114.      public visitstate insertatvisitstate(visitstate inState, Object inElement, boolean inInsertAfter) {
  115.         checkVisitStateType(inState);
  116.  
  117.         if (inElement instanceof Character)
  118.             inElement = (((Character)inElement).toString());
  119.             
  120.         if (!(inElement instanceof String))
  121.              throw new IllegalArgumentException("Can set elements of text only to Strings or Characters");
  122.         
  123.         String str = (String)inElement;
  124.         if (! isChunkSeparator( str.charAt(str.length() -1)))
  125.             str = str + defaultChunkSeparator();
  126.         
  127.         int insertionIndex = ((chunkedtextvisitstate)inState).mCurrentPosition;
  128.         if (inInsertAfter) {
  129.             int nextBounds[] = nextChunk(insertionIndex);
  130.             insertionIndex = nextBounds[1] + 1;
  131.         }
  132.         insertString(insertionIndex, str);    
  133.         return inState;
  134.     } 
  135.     
  136.     /**
  137.      ** indexatvisitstate
  138.      **/    
  139.      public int indexatvisitstate(visitstate inState) {
  140.         checkVisitStateType(inState);
  141.         return (((chunkedtextvisitstate)inState).mCurrentChunkIndex);    
  142.     }
  143.  
  144.  
  145.     /**
  146.      ** visitstateatindex
  147.      **/    
  148.      public visitstate visitstateatindex(int inIndex)  {
  149.         if (inIndex <= 0)                
  150.             throw new IndexOutOfBoundsException("ChunkedText index must be positive");
  151.                         
  152.         int ChunkedTextBounds[] = nextChunk(0); //intialized for debugging purposes.
  153.         int chi = 0;
  154.         int chLast = stringLength();
  155.         for (int wi = 1; wi <= inIndex; wi++){
  156.             if (chi >= chLast) 
  157.                 throw new IndexOutOfBoundsException("ChunkedText chunk index " + wi + " out of bounds");
  158.             ChunkedTextBounds = nextChunk(chi);
  159.             chi = ChunkedTextBounds[1] + 1;
  160.         }
  161.         return new chunkedtextvisitstate (this, ChunkedTextBounds[0], inIndex);
  162.     }
  163.  
  164.  
  165.     /** 
  166.      ** checkVisitStateType -protected-
  167.      **/
  168.     protected void checkVisitStateType(visitstate inState) {
  169.         if (! (inState instanceof chunkedtextvisitstate))
  170.             throw new IllegalArgumentException("Expecting a chunkedtextvisitstate, not a " 
  171.                     + inState.getClass());
  172.     }
  173.             
  174.     /** 
  175.      ** abstract handlers.  must be overridden!
  176.      **/
  177.     protected abstract int[] nextChunk  (int inLookingFrom) ;
  178.         
  179.     protected abstract boolean isChunkSeparator(char inCh);
  180.     protected abstract char    defaultChunkSeparator();
  181.         /*     defaultChunkSeparator and isChunkSeparator are needed so that an extra 
  182.             Separator may be added if necessary when inserting a chunk.  For example, 
  183.             inserting "there" after word 1 of "hello world" should 
  184.             result in "hello there world" rather than "hello thereworld".
  185.             However, if the final char of the chunk being inserted is already a chunk 
  186.             Separator , there is no need to insert a new separator.
  187.         */
  188. }